/*******************************************************************************
 * Copyright 2017.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 *******************************************************************************/

package driver

import (
	"context"
	config "github.com/winc-link/hummingbird-modbus-rtu/config"
	"github.com/winc-link/hummingbird-modbus-rtu/constant"
	"github.com/winc-link/hummingbird-modbus-rtu/internal/servier"
	"github.com/winc-link/hummingbird-sdk-go/commons"
	"github.com/winc-link/hummingbird-sdk-go/model"
	"github.com/winc-link/hummingbird-sdk-go/service"
)

type ModbusRtuProtocolDriver struct {
	sd     *service.DriverService
	server *servier.ModbusServer
}

// DeviceNotify 设备添加/修改/删除通知
func (dr ModbusRtuProtocolDriver) DeviceNotify(ctx context.Context, t commons.DeviceNotifyType, deviceId string, device model.Device) error {
	return nil
}

// ProductNotify 产品添加/修改/删除通知
func (dr ModbusRtuProtocolDriver) ProductNotify(ctx context.Context, t commons.ProductNotifyType, productId string, product model.Product) error {
	return nil
}

// Stop 驱动退出通知。
func (dr ModbusRtuProtocolDriver) Stop(ctx context.Context) error {
	if dr.server != nil {
		dr.server.Stop()
	}
	return nil
}

// HandlePropertySet 设备属性设置
func (dr ModbusRtuProtocolDriver) HandlePropertySet(ctx context.Context, deviceId string, data model.PropertySet) error {
	_, ok := dr.sd.GetDeviceById(deviceId)
	if ok != true {
		_ = dr.sd.PropertySetResponse(deviceId, model.PropertySetResponse{
			MsgId: data.MsgId,
			Data: model.PropertySetResponseData{
				Success:      false,
				Code:         uint32(constant.DeviceNotFound),
				ErrorMessage: string(constant.ErrorCodeMsgMap[constant.DeviceNotFound]),
			},
		})
		return nil
	}
	return nil
}

// HandlePropertyGet 设备属性查询
func (dr ModbusRtuProtocolDriver) HandlePropertyGet(ctx context.Context, deviceId string, data model.PropertyGet) error {
	_, ok := dr.sd.GetDeviceById(deviceId)
	if ok != true {
		_ = dr.sd.PropertyGetResponse(deviceId, model.PropertyGetResponse{
			MsgId: data.MsgId,
			Data:  []model.PropertyGetResponseData{},
		})
		return nil
	}

	return nil
}

// HandleServiceExecute 设备服务调用
func (dr ModbusRtuProtocolDriver) HandleServiceExecute(ctx context.Context, deviceId string, data model.ServiceExecuteRequest) error {
	_, ok := dr.sd.GetDeviceById(deviceId)
	if ok != true {
		_ = dr.sd.ServiceExecuteResponse(deviceId, model.ServiceExecuteResponse{
			MsgId: data.MsgId,
			Data:  model.ServiceDataOut{},
		})
		return nil
	}

	return nil
}

// NewModbusRtuProtocolDriver 协议驱动
func NewModbusRtuProtocolDriver(sd *service.DriverService) *ModbusRtuProtocolDriver {
	cfg := config.GetConfig()
	server := servier.NewModbusServer(cfg, sd)

	server.StartDataWorkers(cfg.WorkerPoolSize)

	sd.GetLogger().Info("Modbus 服务器启动 ")
	if err := server.Start(); err != nil {
		sd.GetLogger().Errorf("服务器启动失败: %v", err)
	}

	return &ModbusRtuProtocolDriver{
		sd:     sd,
		server: server,
	}
}
